﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Mesuro.Equation {
	public class EqOperatorInstance : EqTerm {
		private readonly EqOperatorDefinition definition;
		public EqOperatorDefinition Definition {
			get { return definition; }
		}

		private EqTerm _lhs = null, _rhs = null;

		public EqTerm LHS {
			get { return _lhs; }
			set {
				if (definition.Arguments.HasFlag( EqOperatorArguments.LHS ) || value == null)
					_lhs = value;
				else throw new InvalidOperationException();
			}
		}

		public EqTerm RHS {
			get { return _rhs; }
			set {
				if (definition.Arguments.HasFlag( EqOperatorArguments.RHS ) || value == null)
					_rhs = value;
				else throw new InvalidOperationException();
			}
		}

		public int Precedence {
			get { return definition.Precedence; }
		}

		public EqOperatorInstance( EqOperatorDefinition def )
			: base() {
			definition = def;
		}

		public override EqTerm Evaluate( EqScope scope ) {
			return definition.Evaluate( scope, this );
		}


		public bool HasFlag( EqOperatorFlags flag ) {
			return definition.Flags.HasFlag( flag );
		}

		public override int ComplexityCost() {
			return 1 + LHS.ComplexityCost() + RHS.ComplexityCost();
		}

		public override string ToString() {
			switch (definition.Arguments) {
				case EqOperatorArguments.SINGLE:
					return ' ' + definition.Key + ' ';
				case EqOperatorArguments.PREFIX:
					return definition.Key + ' ' + RHS.ToString();
				case EqOperatorArguments.SUFFIX:
					return LHS.ToString() + ' ' + definition.Key;
				case EqOperatorArguments.BINARY:
				default:
					return '(' + LHS.ToString() + ' ' + definition.Key + ' ' + RHS.ToString() + ')';
			}
		}
	}
}
